package com.psychologyCommunity.Community.Contoller;

import com.mysql.cj.util.StringUtils;
import com.psychologyCommunity.Community.annotation.LoginRequired;
import com.psychologyCommunity.Community.entity.User;
import com.psychologyCommunity.Community.service.FollowService;
import com.psychologyCommunity.Community.service.LikeService;
import com.psychologyCommunity.Community.service.UserService;
import com.psychologyCommunity.Community.util.CommunityConstance;
import com.psychologyCommunity.Community.util.CommunityUtil;
import com.psychologyCommunity.Community.util.HostHolder;
//import org.apache.tomcat.util.http.HeaderUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.OutputStream;

@Controller
@RequestMapping("/user")
public class UserController implements CommunityConstance {
    //处理具体的逻辑过程中，基本上都要用到Logger，当发生问题时都要记日志
    private static final Logger logger= LoggerFactory.getLogger(UserController.class);
    //把上传文件路径 和域名 和项目名 都注入进来，以及处理上传逻辑时也得用到UserService，把这个也注入进来
    @Value("${community.path.upload}")
    private String uploadPath;
    @Value("${community.path.domain}")
    private String domain;
    @Value("${server.servlet.context-path}")
    private String contextPath;
    @Autowired
    private UserService userService;
    //更新的是当前用户的头像，当前用户是谁，就得从hostHolder中拿
    @Autowired
    private HostHolder hostHolder;

    @Autowired
    private FollowService followService;
    //只是得到一个普通的页面，不需要提交，直接用get方式
    @LoginRequired
    @RequestMapping(path = "/setting",method = RequestMethod.GET)
    public String getSettingPage(){
        return "/site/setting";
    }
    //个人主义--显示当前登录用户的主页 ，以及点击头像 能点到对应用户的主页
    @RequestMapping(path ="/profile/{userId}",method = RequestMethod.GET)
    public String getProfilePage(@PathVariable("userId") int userId,Model model){
        User user=userService.findUserById(userId);
        if(user==null){
            throw new RuntimeException("该用户不存在！");
        }
        //用户
        model.addAttribute("user",user);
        //点赞数量
        int likeCount=likeService.findUserLikeCount(userId);
        model.addAttribute("likeCount",likeCount);

        //关注数量
        long followeeCount = followService.findFolloweeCount(userId, ENTITY_TYPE_USER);
        model.addAttribute("followeeCount",followeeCount);
        //粉丝数量
        long followerCount=followService.findFollowerCount(ENTITY_TYPE_USER,userId);
        model.addAttribute("followerCount",followerCount);
        //是否已关注
        boolean hasFollowed=false;
        if(hostHolder.getUser()!=null){ //只有当前用户不为空 才能关注
            hasFollowed=followService.hasFollowed(hostHolder.getUser().getId(),ENTITY_TYPE_USER,userId);
        }
        model.addAttribute("hasFollowed",hasFollowed);

        return "/site/profile";
    }


    //上传提交的时候 表单的请求方式肯定是post
    // --springMvc提供一个数据类型MultipartFile 来接受一个文件，多个可用数组
    // ；我们响应时需要给页面返回一些数据，所以申明一个Model 用它来给模板携带数据
   @LoginRequired
    @RequestMapping(path = "/upload",method = RequestMethod.POST)
    public String uploadHeader(MultipartFile headerImage, Model model){
        if (headerImage==null){
            //如果等于null 就不用处理了，重新回到这个页面 --直接提示 没有选择图片
            model.addAttribute("error","您还没有选择图片！！");
            return "/site/setting";
        }
        //不为空的话 ，就上传，不能直接以上传的文件名直接存在数据库 应该随机生成 避免多个重复（比如很多人传的名字都叫1.png）
        //为了避免重复覆盖，我们就随机生成名字，但后缀也不能变 ，所以先得到这个用户的原始文件名，再把这个文件的后缀存起来
        String fileName=headerImage.getOriginalFilename();
        //从文件中截取后缀 ，然后存起来
        String suffix= fileName.substring(fileName.lastIndexOf("."));//最后一个点的索引往后截取
        //防止后缀是空 ，给个判断提示  --然后重新回到这个页面
        if(StringUtils.isNullOrEmpty(suffix)){
            model.addAttribute("error","文件的格式不正确");
            return "/site/setting";
        }
        //没有问题就生成随机文件名(随机字符串) 然后带上这后缀 --存的时候就按这个文件名来存
        String ImageFileName = CommunityUtil.generateUUID() + suffix;
        //存的时候确定文件存放的路径 --上面注入的存储的文件夹的路径---存在数据库中的肯定是F:/Java/springBoot/upload/随机文件名
        File destImg=new File(uploadPath+"/"+ImageFileName);
        try {
            headerImage.transferTo(destImg);//把上传的文件内容headerImage，写入的这个文件路径中
        } catch (IOException e) {
            //出错就打印日志，抛出出错的原因
            logger.error("上传文件失败"+e.getMessage());
            throw new RuntimeException("上传文件失败，服务器发生异常！！"+e);
        }
        //访问者肯定是不能通过 本地路径 uploadPath+"/"+ImageFileName 访问到我们的资源，我们需要给别人提供web访问路径
        //例如:http://localhost:8888/community/user/header/xxx.png 我们给用户提供这种形式的//更新当前用户的头像的路径
        User user = hostHolder.getUser();//得到当前用户
       //允许用户访问的web路径 要注意此时找的就不是原始文件名，而是随机文件名后缀 --之前的出错原因
        String headerUrl = domain + contextPath + "/user/header/" + ImageFileName;
       //把当前用户的头像传入
        userService.updateHeader(user.getId(), headerUrl);
        //到这就算更新完成成功，直接重定向跳到首页。可以看到当前用户的头像变化了
        return "redirect:/index";

    }

    //获取头像的服务 :http://localhost:8888/community/user/header/xxx.png 路径格式就不能随意了 就得按照这个来拼
    @RequestMapping(path = "/header/{fileName}",method = RequestMethod.GET)
    public void getHeader(@PathVariable("fileName") String fileName, HttpServletResponse response){
        //服务器存放路径 ，-覆盖-带上本地路径的fileName
        fileName=uploadPath+"/"+fileName;

        //文件后缀
        String suffixA = fileName.substring(fileName.lastIndexOf("."));
        //响应 图片，文件的格式是得带上文件格式
        response.setContentType("image/"+suffixA);
        try(
                //读取一个文件 得到一个输入流 --肯定不是一个一个字节输出 建立一个缓冲区
                FileInputStream fileInputStream = new FileInputStream(fileName);
                // --响应的图片是二进制数据，得用到字节流
             OutputStream outputStream = response.getOutputStream();

                ){

            byte[] buffer=new byte[1024];
            int b=0;
            while((b=fileInputStream.read(buffer))!=-1){ //==-1 表示数据读完了，直接退出，没读完就循环读
                outputStream.write(buffer,0,b);//写到缓冲区，从0开始写到b
            }
        } catch (IOException e) {
            logger.error("读取头像失败："+e.getMessage());
        }

    }
    @Autowired
    private LikeService likeService;

}
